package com.liushao.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.liushao.entity.Lend;
import com.liushao.entity.LendItem;
import com.liushao.entity.bo.TransFlowBO;
import com.liushao.entity.vo.InvestVO;
import com.liushao.enums.TransTypeEnum;
import com.liushao.hfb.FormHelper;
import com.liushao.hfb.HfbConst;
import com.liushao.hfb.RequestHelper;
import com.liushao.mapper.LendItemMapper;
import com.liushao.mapper.LendMapper;
import com.liushao.mapper.UserAccountMapper;
import com.liushao.service.LendItemService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.liushao.service.LendService;
import com.liushao.service.TransFlowService;
import com.liushao.service.UserBindService;
import com.liushao.util.LendNoUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 标的出借记录表 服务实现类
 * </p>
 *
 * @author chen
 * @since 2025-01-03
 */
@Service
public class LendItemServiceImpl extends ServiceImpl<LendItemMapper, LendItem> implements LendItemService {


    @Autowired
    private LendMapper lendMapper;

    @Autowired
    private LendService lendService;

    @Autowired
    private UserBindService userBindService;

    @Autowired
    private TransFlowService transFlowService;

    @Autowired
    private UserAccountMapper userAccountMapper;

    @Override
    public String commitInvest(InvestVO investVO) {

        Long lendId = investVO.getLendId();//标的的id
        Lend lend = lendMapper.selectById(lendId);//标的对象
        //判断状态必须是 募资中 ??? 自己写

        //   募资中 √   标的不能超卖    账户中余额充足

        //   标的不能超卖 ( 已经投资金额+本次投资金额>标的金额 )这就是超卖  add   自己做
        // BigDecimal bigDecimal=null;


        //账户中余额充足  当前用户的余额 >= 当前用户的投资金额  自己写

        //上述三个都没有问题
        //标的下面生成投资信息
        LendItem lm = new LendItem();
        lm.setInvestUserId(investVO.getInvestUserId());//投资人id
        lm.setInvestName(investVO.getInvestName());//投资人姓名

        String lendItemNo = LendNoUtils.getLendItemNo();//投资条目编号
        lm.setLendItemNo(lendItemNo);

        lm.setLendId(investVO.getLendId());//标的编号
        lm.setInvestAmount(new BigDecimal(investVO.getInvestAmount()));//投资金额
        lm.setLendYearRate(lend.getLendYearRate());//年化率
        lm.setLendStartDate(lend.getLendStartDate());//开始时间
        lm.setInvestTime(new Date());//投资时间
        lm.setLendEndDate(lend.getLendEndDate());//投资结束时间

        //预期收益
        BigDecimal interestCount = lendService.getInterestCount(
                lm.getInvestAmount(),
                lm.getLendYearRate(),
                lend.getPeriod(),
                lend.getReturnMethod());

        lm.setExpectAmount(interestCount);

        //实际收益
        lm.setRealAmount(new BigDecimal(0));
        lm.setStatus(0);

        baseMapper.insert(lm);


        String bindCode=  userBindService.getBindCodeByUserId(investVO.getInvestUserId());
        String benefitBindCode=  userBindService.getBindCodeByUserId(lend.getUserId());

        Map<String,Object> paramMap = new HashMap<>();
        paramMap.put("agentId", HfbConst.AGENT_ID);//给商户分配的唯一标识
        paramMap.put("voteBindCode",bindCode);//投资人绑定协议号
        paramMap.put("benefitBindCode",benefitBindCode);//借款人绑定协议号
        paramMap.put("agentProjectCode",lend.getLendNo());//项目编号
        paramMap.put("agentProjectName",lend.getTitle());//项目名称
        paramMap.put("agentBillNo",lendItemNo);//商户订单号
        paramMap.put("voteAmt",investVO.getInvestAmount());// 投资金额
        paramMap.put("voteFeeAmt",new BigDecimal(0));// 商户手续费
        paramMap.put("projectAmt",new BigDecimal(investVO.getInvestAmount()));// 总金额  这就是10w
        paramMap.put("returnUrl", HfbConst.INVEST_RETURN_URL);//绑定完成后同步返回商户的完整地址
        paramMap.put("notifyUrl",HfbConst.INVEST_NOTIFY_URL);//绑定完成后异步通知商户的完整地址。
        paramMap.put("timestamp",new Date().getTime());//时间戳
        paramMap.put("sign", RequestHelper.getSign(paramMap));//验签参数


        String form = FormHelper.buildForm(HfbConst.INVEST_URL, paramMap);//第一个参数是 用户绑定的url   ，第二个 接口需要的参数 !!

        return form;

    }
@Transactional(rollbackFor = Exception.class)
    @Override
    public void notifyss(Map<String, Object> objectMap) {
        System.out.println("-----------投标成功了----------");
        //获取投资编号
        // agent_bill_no	string	50	是	商户订单号。
        String agentBillNo = (String) objectMap.get("agentBillNo");
        //幂等性 !!!
        boolean result
                = transFlowService.isSaveTransFlow(agentBillNo);
        if(result){
            System.out.println("幂等性返回!!");
            return;
        }
        //获取 vote_bind_code	string	50	是	投资人绑定协议号
        String voteBindCode = (String) objectMap.get("voteBindCode");
        //vote_amt	decimal		是	投资金额
        //(含商户奖励给投资人的金额，即包括vote_prize_amt)

        String voteAmt = (String) objectMap.get("voteAmt");

        //修改余额和冻结的金额
        userAccountMapper.updateUserAccount(voteBindCode,
                new BigDecimal("-"+voteAmt),
                new BigDecimal(voteAmt));

        //修改投资记录的状态变为 已经支付
        LendItem lendItem = this.getByLendItemNo(agentBillNo);
        lendItem.setStatus(1);
        baseMapper.updateById(lendItem);

        //修改标的信息  投资人数 已经投资的金额
    Long lendId = lendItem.getLendId();
    Lend lend = lendMapper.selectById(lendId);
    lend.setInvestNum(lend.getInvestNum()+1);
    lend.setInvestAmount(lend.getInvestAmount().add(lendItem.getInvestAmount()));
    lendMapper.updateById(lend);

    //动钱了 交易流水
    /*
         private String agentBillNo;//商户充值订单号
    private BigDecimal amount;//账户的可用余额
    private String bindCode;//绑定
    private TransTypeEnum transTypeEnum;//绑定协议号
    private String memo;//备忘
     */
    TransFlowBO transFlowBO = new TransFlowBO(
          agentBillNo,
          new BigDecimal(voteAmt),
          voteBindCode,
            TransTypeEnum.INVEST_LOCK,
            "项目编号:"+lend.getLendNo()+",项目名称："+lend.getTitle()
    );










}

    @Override
    public List<LendItem> selectLendById(Long lendId, int status) {
        QueryWrapper<LendItem> wrapper = new QueryWrapper<>();
        wrapper.eq("lend_id",lendId);
        wrapper.eq("status",status);
        List<LendItem> lendItemList = baseMapper.selectList(wrapper);

        return lendItemList;
    }

    @Override
    public List<LendItem> selectLendById(Long lendId) {
        QueryWrapper<LendItem> wrapper = new QueryWrapper<>();
        wrapper.eq("lend_id",lendId);

        List<LendItem> lendItemList = baseMapper.selectList(wrapper);

        return lendItemList;
    }

    //写个辅助方法
    public  LendItem getByLendItemNo(String lendItemNo){
        QueryWrapper<LendItem> wrapper = new QueryWrapper<>();
        wrapper.eq("lend_item_no",lendItemNo);
        return  baseMapper.selectOne(wrapper);
    }

}
